In   -
Out  SolveHanoi
Type Module
Ver  1.00c

Define Module
 Name      SolveHanoi
 Author    Justin Fletcher
 Commands
  Name     SolveHanoi
  Code     main
  Help     ...
           Solve will solve the tower of hanoi problem for 3 discs.
 End Commands
End Module

; *******************************************************************
; Subroutine:   main
; Description:  Initialises the registers and calls the Hanoi routine
;               to solve the problem
; Parameters:   none
; Returns:      All registers, status flags and interrupts preserved
; *******************************************************************
.main
   STMFD   (sp)!,{r0-r3,link}            ; Stack registers
   MOV     r0,#3                         ; number of discs
   MOV     r1,#ASC("A")                  ; name of tower to start from
   MOV     r2,#ASC("B")                  ; name of tower to end on
   MOV     r3,#ASC("C")                  ; name of tower for storage
   BL      Hanoi                         ; solve the problem
   LDMFD   (sp)!,{r0-r3,pc}^             ; Return from call

; *******************************************************************
; Subroutine:   Hanoi
; Description:  Recursive routine to solve the tower of Hanoi problem
;               as supplied in Assignment 9.
; Parameters:   r0 = number of discs
;               r1 = name of stack to move from
;               r2 = name of stack to move to
;               r3 = temporary stack
; Returns:      All registers, status flags and interrupts preserved
; *******************************************************************
.Hanoi
   STMFD   (sp)!,{r0-r3,link}            ; Stack registers
   CMP     r0,#0                         ; end of iteration ?
   BLE     $exit                         ; if so, exit
   SUB     r0,r0,#1                      ; decrement r1
   SWAP    r2,r3                         ; swap the end two columns (A,C,B)
   BL      Hanoi                         ; recurse
   REM     "Move from %C"                ; don't split lines
   XSWI    "OS_WriteC",r1                ; write A to the screen
   REM     " to %C"                      ; again, don't split
   XSWI    "OS_WriteC",r3                ; write B to the screen (which is
                                         ; now in r3 !)
   SWI     "OS_NewLine"                  ; a blank line
   LDMFD   (sp),{r0-r3}                  ; restore from stack without WB
   SUB     r0,r0,#1                      ; decrement again
   SWAP    r1,r3                         ; swap r1 and r3
   BL      Hanoi                         ; recurse
$exit
   LDMFD   (sp)!,{r0-r3,pc}              ; Return from call

#Post
#Run <CODE>
